package com.pangus.toolkits.files.model;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.pangus.toolkits.files.download.DownloadStrategy;
import com.pangus.toolkits.files.download.DownloadStrategyFactory;
import com.pangus.toolkits.files.errors.check.HttpException;
import com.pangus.toolkits.files.http.Response;
import com.pangus.toolkits.files.operation.FSFileOperation;
import lombok.Getter;

import javax.annotation.Nullable;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.nio.file.NotDirectoryException;

/**
 * @author yingheng chen
 * @description 文件属性及操作
 * @date 2019/12/3
 */
public class FileLink implements Serializable, FileOperation {
    /**
     * 文件信息
     */
    private final FileInfo fileInfo;
    private FSFileOperation fileOperation;
    private DownloadStrategy downloadStrategy;
    /**
     * 文件是否有效
     */
    @Getter
    private boolean available;

    public FileLink(FileInfo fileInfo, FSFileOperation fileOperation) {
        this.fileInfo = fileInfo;
        this.fileOperation = fileOperation;
        this.available = true;
        this.downloadStrategy = DownloadStrategyFactory.create(fileInfo, fileOperation);
    }


    @Override
    public File download(String directory) throws IOException {
        return this.download(directory, null);
    }

    /**
     *
     * @param directory 本地文件夹路径,可以为相对或绝对路径
     * @return
     * @throws IOException
     */
    @Override
    public File download(String directory, @Nullable String filename) throws IOException {
        checkState();
        if (StrUtil.isBlank(filename)) {
            filename = fileInfo.getName();
        }
        final File dir = FileUtil.mkdir(directory);
        if (!FileUtil.isDirectory(dir)) {
            throw new NotDirectoryException(directory);
        }
        return downloadStrategy.download(dir, filename);
    }


    @Override
    public void delete() throws IOException {
        checkState();
        final Response<Boolean> response = this.fileOperation.deleteFile(this.fileInfo);
        final JSONObject jsonObject = response.getJsonObject();
        if (!jsonObject.getBoolean("isSuccess")) {
            throw new HttpException(jsonObject.getInteger("code"), jsonObject.getString("msg"));
        }
        this.available = false;
    }

    @Nullable
    @Override
    public FileInfo getFileInfo() {
        checkState();
        return fileInfo;
    }

    private void checkState() {
        if (!this.available) {
            throw new IllegalStateException("file link is not available,it may be  deleted");
        }
    }



}
